home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 18
/
CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso
/
CUCD
/
Magazine
/
C_Tutorial
/
Part-4
/
screen5.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-08-31
|
11KB
|
403 lines
/* First, include our own supporting header files, i.e., clip.h */
#include "clip.h"
#include<exec/libraries.h>
#include<intuition/intuition.h>
#include<utility/tagitem.h>
#include<graphics/text.h>
#include<graphics/rastport.h>
#include<intuition/screens.h>
#include<libraries/gadtools.h>
#include<string.h>
#include<stdio.h>
#include<clib/exec_protos.h>
#include<clib/graphics_protos.h>
#include<clib/intuition_protos.h>
#include<clib/gadtools_protos.h>
/* The library base global variables */
/* (The different style of opening libraries requires these to be initialised to NULL) */
struct Library* GfxBase = NULL;
struct Library* IntuitionBase = NULL;
struct Library* LayersBase = NULL;
struct Library* GadToolsBase = NULL;
/* The global handle on the palette gadget */
struct Gadget* palgad = NULL;
/* Global record of foreground pen */
UBYTE pen;
/* Need to give prototypes for our functions */
void handleIDCMP(struct Window*);
void setupWindow();
void createWindow(struct Gadget*, struct Screen*, struct Menu*);
int openLibs();
void closeLibs();
struct Menu* createMenuStrip(APTR);
void setFgPen(struct Window*, int);
void doGadgetUp(struct Window*, struct IntuiMessage*);
int doMenuPick(struct Window*, struct IntuiMessage*);
/* Some constants for the position and size of our gadget */
#define MYBUT_LEFT (10)
#define MYBUT_TOP (5)
#define MYBUT_WIDTH (80)
#define MYBUT_HEIGHT (12)
#define MYBUT_TEXT "Next Pen"
#define MYBUT_ID (0)
#define MYPAL_LEFT (170)
#define MYPAL_TOP (2)
#define MYPAL_WIDTH (109)
#define MYPAL_HEIGHT (19)
#define MYPAL_TEXT "Colour:"
#define MYPAL_ID (1)
#define MYPAL_DEPTH (4)
/* The top gap required around the gadgets */
#define MYTOPGAP (30)
/* The initial pen colour */
#define MYINITPEN (1)
/* The start of the program */
void main()
{
/* Use a different style of opening libraries... */
if(openLibs())
{
/* Now do the real work */
setupWindow();
}
/* Matched call to close libraries */
closeLibs();
}
/* Try to open all the libraries -- return TRUE on success */
int openLibs()
{
if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
{
printf("Error: could not open graphics.library\n");
return FALSE;
}
if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
{
printf("Error: could not open intuition.library\n");
return FALSE;
}
if((LayersBase = OpenLibrary("layers.library",37)) == NULL)
{
printf("Error: could not open layers.library\n");
return FALSE;
}
if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
{
printf("Error: could not open gadtools.library\n");
return FALSE;
}
return TRUE;
}
/* Close any open library */
void closeLibs()
{
if(GadToolsBase)
CloseLibrary(GadToolsBase);
if(LayersBase)
CloseLibrary(LayersBase);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
if(GfxBase)
CloseLibrary(GfxBase);
}
/* Setup the window -- do the GadTools stuff */
void setupWindow()
{
struct Screen* scr;
UWORD pens[] = { ~0 };
/* Try to open a new screen with 16 colours (four bitplanes deep) */
if(scr = OpenScreenTags(NULL,
SA_Depth, 4,
/* Enable 3D look by specifying SA_Pens */
SA_Pens, pens,
TAG_DONE))
{
APTR vinfo;
/* Get the visual info so GadTools can render the gadgets nicely */
if(vinfo = GetVisualInfo(scr, TAG_DONE))
{
/* We can initialise glist in its declaration */
struct Gadget* glist = NULL;
struct Gadget* gad;
int offtop, offleft;
struct NewGadget newgad;
/* Initialised structure declaration: describes 8pt Topaz font */
struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
/* Start a GadTools gadget list */
gad = CreateContext(&glist);
/* The offsets of our window borders */
offleft = scr->WBorLeft;
offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
/* Setup our first gadget */
newgad.ng_TextAttr = &topazFont;
newgad.ng_VisualInfo = vinfo;
newgad.ng_LeftEdge = MYBUT_LEFT + offleft;
newgad.ng_TopEdge = MYBUT_TOP + offtop;
newgad.ng_Width = MYBUT_WIDTH;
newgad.ng_Height = MYBUT_HEIGHT;
newgad.ng_GadgetText = MYBUT_TEXT;
newgad.ng_GadgetID = MYBUT_ID;
newgad.ng_Flags = 0;
/* Now create it and add it to our list */
gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
/* Setup our second gadget */
/* (We can reuse newgad, and just change the different bits) */
newgad.ng_LeftEdge = MYPAL_LEFT + offleft;
newgad.ng_TopEdge = MYPAL_TOP + offtop;
newgad.ng_Width = MYPAL_WIDTH;
newgad.ng_Height = MYPAL_HEIGHT;
newgad.ng_GadgetText = MYPAL_TEXT;
newgad.ng_GadgetID = MYPAL_ID;
newgad.ng_Flags = 0;
/* Now create it and add it to our list */
if(gad = CreateGadget(PALETTE_KIND, gad, &newgad,
/* Initially selected pen */
GTPA_Color, MYINITPEN,
/* Depth: 2 to the power MYPAL_DEPTH colours */
GTPA_Depth, MYPAL_DEPTH,
/* Gadget will indicate selection */
GTPA_IndicatorWidth, 16,
TAG_DONE))
{
struct Menu* menustrip;
/* Remember gadget pointer so we can affect it in message handler */
palgad = gad;
if(menustrip = createMenuStrip(vinfo))
/* If succeeded then all gadgets and menus created */
createWindow(glist, scr, menustrip);
FreeMenus(menustrip);
}
else
printf("Error: could not create gadget(s)\n");
/* Free all the gadgets that were created */
FreeGadgets(glist);
FreeVisualInfo(vinfo);
}
else
printf("Error: could not get visual info\n");
CloseScreen(scr);
}
else
printf("Error: could not create screen\n");
}
/* Create the menu strip, using GadTools menu functions */
struct Menu* createMenuStrip(APTR vinfo)
{
/* The description of our menus */
struct NewMenu mymenu[] =
{
{ NM_TITLE, "Project", 0, 0, 0, 0,},
{ NM_ITEM, "Quit", "Q", 0, 0, 0,},
{ NM_TITLE, "Pen", 0, 0, 0, 0,},
{ NM_ITEM, "Next", "N", 0, 0, 0,},
{ NM_ITEM, "Prev", "P", 0, 0, 0,},
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,},
{ NM_ITEM, "Reset", "R", 0, 0, 0,},
{ NM_END, NULL, 0, 0, 0, 0,},
};
struct Menu* menustrip;
if (menustrip = CreateMenus(mymenu, TAG_END))
{
if (LayoutMenus(menustrip, vinfo, TAG_END))
/* Succeeded, so return menu strip */
return menustrip;
else
{
/* Failed, so must deallocate before returning */
FreeMenus(menustrip);
printf("Error: could not layout menus\n");
}
}
else
printf("Error: could not create menu strip\n");
/* Failed, so return NULL */
return NULL;
}
/* Actually open the window, in the normal way */
void createWindow(struct Gadget* glist, struct Screen* scr, struct Menu* menustrip)
{
struct Window* win;
/* Open our window */
if(win = OpenWindowTags(NULL,
WA_Left, 0,
WA_Top, 0,
/* Make the window the same size as the screen */
WA_Width, scr->Width,
WA_Height, scr->Height,
WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
WA_Gadgets, glist,
WA_CustomScreen, scr,
TAG_DONE, 0))
{
/* If window opened, set clip region */
if(setClipInternal(win))
{
/* Attach menu strip to window */
if(SetMenuStrip(win, menustrip))
{
/* Let GadTools refresh its bits of the window */
GT_RefreshWindow(win, NULL);
/* Now handle messages */
handleIDCMP(win);
/* Remove menu strip */
ClearMenuStrip(win);
}
else
printf("Error: could not attach menus to window\n");
removeClip(win);
}
else
printf("Error: could not set clip region on window\n");
CloseWindow(win);
}
else
printf("Error: could not open window\n");
}
/* Our message handling code */
void handleIDCMP(struct Window* win)
{
char* text = "Hello World!";
int going = TRUE;
int drawing = FALSE;
setFgPen(win, MYINITPEN);
/* Set the drawing mode to draw only the foreground of text, not the background */
SetDrMd(win->RPort, JAM1);
while(going)
{
struct IntuiMessage* intuimsg;
/* Wait for messages to arrive */
WaitPort(win->UserPort);
/* Messages have arrived: loop through all of them */
while(intuimsg = GT_GetIMsg(win->UserPort))
{
/* Act on this message... */
switch(intuimsg->Class)
{
case IDCMP_MOUSEBUTTONS:
switch(intuimsg->Code)
{
case SELECTDOWN:
drawing = TRUE;
break;
case SELECTUP:
drawing = FALSE;
break;
}
/* break; omitted so we draw on click, too */
case IDCMP_MOUSEMOVE:
/* Don't draw on top gap which holds gadgets */
if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
{
Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
Text(win->RPort, text, strlen(text));
}
break;
case IDCMP_CLOSEWINDOW:
going = FALSE;
break;
case IDCMP_REFRESHWINDOW:
/* You *MUST* remember to ask for and handle these refresh messages */
GT_BeginRefresh(win);
GT_EndRefresh(win, TRUE);
break;
case IDCMP_GADGETUP:
doGadgetUp(win, intuimsg);
break;
case IDCMP_MENUPICK:
going = doMenuPick(win, intuimsg);
break;
}
/* Reply when finished with message */
GT_ReplyIMsg(intuimsg);
}
}
}
/* Set foreground pen of window */
void setFgPen(struct Window* win, int value)
{
/* Wrap when reached the end of the palette gadget's colours */
pen = value % (1<<MYPAL_DEPTH);
SetAPen(win->RPort, pen);
/* If the palette gadget has been made, update it with new pen value */
if(palgad)
GT_SetGadgetAttrs(palgad, win, NULL, GTPA_Color, pen, TAG_DONE);
}
/* Process IDCMP_GADGETUP event */
void doGadgetUp(struct Window* win, struct IntuiMessage* intuimsg)
{
struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
switch(gad->GadgetID)
{
case MYBUT_ID:
/* Our button was clicked! Set foreground to next pen colour */
setFgPen(win, pen+1);
break;
case MYPAL_ID:
/* Our palette gadget was clicked! Set foreground to gadget colour */
setFgPen(win, intuimsg->Code);
break;
}
}
/* Process IDCMP_MENUPICK event */
int doMenuPick(struct Window* win, struct IntuiMessage* intuimsg)
{
UWORD menuCode, menuNumber, itemNumber;
/* Loop over all the menu selections in the menu code */
for(menuCode = intuimsg->Code;
menuCode != MENUNULL;
menuCode = ItemAddress(win->MenuStrip, menuCode)->NextSelect)
{
/* Extract the menu number and menu item number from the menu code */
menuNumber = MENUNUM(menuCode);
itemNumber = ITEMNUM(menuCode);
/* Now decide what to do based on what menu item was selected */
switch(menuNumber)
{
case 0: /* Project menu */
/* Only one item: Quit */
if(itemNumber == 0)
return FALSE; /* Stop going */
break;
case 1: /* Pen menu */
switch(itemNumber)
{
case 0: /* Next */
setFgPen(win, pen+1);
break;
case 1: /* Prev */
setFgPen(win, pen-1);
break;
case 3: /* Reset (item 2 is the bar!) */
setFgPen(win, MYINITPEN);
break;
}
break;
}
}
/* Keep going */
return TRUE;
}